package config

import (
	"errors"
	"gopkg.in/yaml.v2"
	"io"
	"os"
	"sync"
)

type Config struct {
	Server   Server   `yaml:"server"`
	Cache    Cache    `yaml:"cache"`
	Database Database `yaml:"database"`
	Log      Log      `yaml:"log"`
}

// 定义全局变量
var (
	cfg        *Config
	configLock sync.Mutex
)

// InitConfig 初始化数据库配置
func InitConfig(env *string) (c *Config, err error) {
	configLock.Lock()
	defer configLock.Unlock()

	if cfg != nil {
		return cfg, nil
	}

	var configFile = "config_dev.yaml"
	//选择需要实例化的配置文件
	switch *env {
	case "production":
		configFile = "config_prod.yaml"
	case "dev":
		configFile = "config_dev.yaml"
	}
	configFile = "internal/config/" + configFile

	//读取配置文件
	var (
		file *os.File
		n    int
	)
	if file, err = os.Open(configFile); err != nil {
		return nil, err
	}
	defer file.Close()

	var b = make([]byte, 1024*16)
	var data = make([]byte, 0)
	for {
		n, err = file.Read(b)
		if err != nil && err != io.EOF {
			return nil, err
		}
		data = append(data, b[:n]...)

		//判断读取完毕
		if err == io.EOF {
			break
		}
	}

	//将字节数组解析为对象
	if err = yaml.Unmarshal(data, &c); err != nil {
		return nil, err
	}

	cfg = c
	return cfg, nil
}

// GetConfig 获取配置文件
func GetConfig() (*Config, error) {
	if cfg == nil {
		return nil, errors.New("config is nil")
	}

	return cfg, nil
}
